#include "loglevel.h"
#include <iostream>

#define RESET "\033[0m"
#define BLACK "\033[30m"              /* Black */
#define RED "\033[31m"                /* Red */
#define GREEN "\033[32m"              /* Green */
#define YELLOW "\033[33m"             /* Yellow */
#define BLUE "\033[34m"               /* Blue */
#define MAGENTA "\033[35m"            /* Magenta */
#define CYAN "\033[36m"               /* Cyan */
#define WHITE "\033[37m"              /* White */
#define BOLDBLACK "\033[1m\033[30m"   /* Bold Black */
#define BOLDRED "\033[1m\033[31m"     /* Bold Red */
#define BOLDGREEN "\033[1m\033[32m"   /* Bold Green */
#define BOLDYELLOW "\033[1m\033[33m"  /* Bold Yellow */
#define BOLDBLUE "\033[1m\033[34m"    /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
#define BOLDCYAN "\033[1m\033[36m"    /* Bold Cyan */
#define BOLDWHITE "\033[1m\033[37m"   /* Bold White */
#define BRIGHTGREEN "\033[92m"        /* Bright Green */
#define BRIGHTYELLOW "\033[93m"       /* Bright Yellow */
namespace vlog
{

const char* LogLevel::ToString(const vlog::LogLevel::Level& leve) noexcept
{
    switch (leve)
    {
#define XX(name)                                                                                                       \
    case vlog::LogLevel::Level::name:                                                                                  \
    {                                                                                                                  \
        return #name;                                                                                                  \
    }

        XX(UNKONW)
        XX(DEBUG)
        XX(ERROR)
        XX(FATAL)
        XX(WARN)
        XX(INFO)
#undef XX
    default:
        return "UNKONW_LEVEL";
        break;
    }

    return "UNKONW_LEVEL";
}

const vlog::LogLevel::Level LogLevel::FromString(const std::string& strLevel) noexcept
{
#define XX(name, val)                                                                                                  \
    if (strLevel == #val)                                                                                              \
    {                                                                                                                  \
        return Level::name;                                                                                            \
    }

    XX(DEBUG, debug)
    XX(UNKONW, unkonw)
    XX(ERROR, error)
    XX(FATAL, fatal)
    XX(WARN, warn)
    XX(INFO, info)

    XX(DEBUG, DEBUG)
    XX(UNKONW, UNKONW)
    XX(ERROR, ERROR)
    XX(FATAL, FATAL)
    XX(WARN, WARN)
    XX(INFO, INFO)
#undef XX
    return Level::UNKONW;
}

std::string_view LogLevel::GetLevelColor(const vlog::LogLevel::Level& level) noexcept
{
    switch (level)
    {
    case vlog::LogLevel::Level::ERROR:
        return RED;
        break;
    case vlog::LogLevel::Level::DEBUG:
        return WHITE;
        break;
    case vlog::LogLevel::Level::INFO:
        return BOLDMAGENTA;
        break;
    case vlog::LogLevel::Level::FATAL:
        return BRIGHTGREEN;
        break;
    case vlog::LogLevel::Level::WARN:
        return BRIGHTYELLOW;
        break;
    default:
        return RESET;
        break;
    }
    return RESET;
}

} // namespace vlog
